import React from 'react';
import { Table, Popconfirm, Form, Button } from 'antd';
import EditableCell from './EditableCell';

export const EditableContext = React.createContext(); // 创建一个context对象
const EditableRow = ({ form, index, ...props }) => (
  // 接收一个value值.提供消费组件使用
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
);
// 挂载暴露form属性
const EditableFormRow = Form.create()(EditableRow);

/* 可单行编辑表格（有demo演示文件夹）
  某一行编辑状态，可以指定行内某个字段不可编辑 表头内定义字段editable: false
  组件调用案例：
  <EditableTableCustomTypes
    columns={this.columnsEditable}
    dataSource={dataSource} // 渲染的数据源
    handleSaveTable={this.handleSaveTable} // 保存编辑回调（添加回调函数，才显示按钮）
    handleDelTable={this.handleDelTable} // 删除行回调（添加回调函数，才显示按钮）
    addRowData={this.state.addRowData} // 新增行的数据源
    ref={(child) => { this.childTableDom = child; }} // 新增所需要的ref事件，触发子组件函数
    // 指定区域内，可以传入所有table参数API
    optsTable={{
      // scroll: { x: '100%' }, // 横向滚动
    }}
  />
*/
class EditableTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      editingKey: '', // 记录编辑状态的key
      dataSource: [], // 表格内数据
      saveFlag: true, // 保存按钮状态记录 true可新增编辑
    };
    this.columns = []; // 表头

    // 案例表头
    // this.columns = [
    //   {
    //     title: '输入框',
    //     dataIndex: 'name',
    //     width: '25%',
    //     // editable: true, // 是否可编辑
    //     textType: 'input' // 进入编辑状态的是哪种输入框，类型有如下
    //     // selectYesNo下拉（是否）， selectEnable下拉（启用/禁用） inputNumber数值框
    //     // selectCustom自定义下拉框数据
    //   },
    //   {
    //     title: '数值选择框',
    //     dataIndex: 'age',
    //     width: '15%',
    //     editable: true,
    //     textType: 'inputNumber'
    //   },
    //   {
    //     title: '选项框',
    //     dataIndex: 'address',
    //     width: '40%',
    //     editable: true,
    //     textType: 'selectYesNo',
    //     render: (text) => {
    //       return text === '0' ? '是' : '否'
    //     }
    //   },
    //   {
    //     title: '动态传值选项框',
    //     dataIndex: 'selectCustom',
    //     width: '40%',
    //     editable: true,
    //     textType: 'selectCustom',
    //     selectCustomData: ['李组长', '真组件', '父组件'], // 动态下拉选项，在此更新值
    //   },
    // ];
  }

  componentWillMount() {
    const { columns, dataSource, handleDelTable, handleSaveTable } = this.props;
    this.columns = columns; // 表头

    // 追加操作栏表头
    this.columns.push({
      title: 'operation',
      dataIndex: 'operation',
      render: (text, record) => {
        const editable = this.isEditing(record);
        return (
          <div>
            {editable ? (
              <span>
                <EditableContext.Consumer>
                  {form => (
                    <Button
                      onClick={() => this.onSaveRow(form, record.key)}
                      style={{ marginRight: 8 }}
                    >
                      保存
                    </Button>
                  )}
                </EditableContext.Consumer>
                <Popconfirm title="Sure to cancel?" onConfirm={() => this.onCancelRow(record.key)}>
                  <Button>取消</Button>
                </Popconfirm>
              </span>
            ) : (
              <span>
                {handleSaveTable ? (
                  <Button onClick={() => this.onEditRow(record.key)}>编辑</Button>
                ) : null}
                {handleDelTable ? (
                  <Button onClick={() => this.onDeleteRow(record.key)}>删除</Button>
                ) : null}
              </span>
            )}
          </div>
        );
      },
    });
    this.setState({
      dataSource,
    });
  }

  // 编辑按钮
  onEditRow(key) {
    // 点击编辑时存放key值，对比用
    this.setState({
      editingKey: key,
    });
  }

  // 保存按钮
  onSaveRow(form, key) {
    // row是当前改变后的数据（当前表格行的所有）
    form.validateFields((error, row) => {
      if (error) {
        return;
      }
      const dataSource = this.state.dataSource;
      const newData = [...dataSource];
      const index = newData.findIndex(item => key === item.key); // 找到指定数据的索引

      if (index > -1) {
        const item = newData[index]; // 获取当前行旧数据源
        const mergeRow = {
          ...item, // 旧数据(要把key等数据一起合并)
          ...row, // 新数据
        };

        // 替换老数据成新数据
        newData.splice(index, 1, mergeRow);

        // 更改后的行数据传递给父组件处理
        this.props.handleSaveTable(mergeRow);
      } else {
        newData.push(this.state.dataSource);
      }

      // 更新数据
      this.setState({
        dataSource: newData,
        editingKey: '',
        saveFlag: true,
      });
    });
  }

  // 删除按钮
  onDeleteRow(recordKey) {
    const { dataSource } = this.state;
    setTimeout(() => {
      const index = dataSource.findIndex(item => item.key === recordKey);
      const delData = dataSource[index]; // 删除的数据
      // 找到指定删除的位置
      if (index > -1) {
        dataSource.splice(index, 1); // 删除一条
        this.setState({
          dataSource,
        });
      }

      // 父组件删除回调, 返回删除的那条数据，及整体更新后的数据源
      this.props.handleDelTable(delData, dataSource);
    });
  }

  // 判断是否编辑状态
  isEditing = record => {
    return record.key === this.state.editingKey;
  };

  // 取消按钮
  onCancelRow = () => {
    this.setState({ editingKey: '' });
  };

  // 新增按钮
  onAddEditRow = () => {
    const { dataSource, saveFlag } = this.state;
    const dataSourceLen = dataSource.length;
    const objStr = JSON.stringify(dataSource[0]);
    const handleRowData = JSON.parse(objStr);
    // 某行编辑状态没有保存时，不可在新增
    if (!saveFlag) return;

    // 创建一个全新空的行数据
    Object.keys(handleRowData).forEach(key => {
      // 单独处理key值，key值不同才能判断编辑表格状态
      if (key === 'key') {
        handleRowData[key] = dataSourceLen;
      } else {
        handleRowData[key] = null;
      }
    });

    dataSource.push(handleRowData); // 添加一行数据
    this.setState({
      dataSource,
      editingKey: dataSource.length - 1, // 当前新增行可编辑状态
      saveFlag: false,
    });
  };

  render() {
    const components = {
      body: {
        row: EditableFormRow,
        cell: EditableCell,
      },
    };

    const columns = this.columns.map(col => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        // 传递给子组件使用的参数
        onCell: record => ({
          record,
          textType: col.textType || 'text', // 编辑类型
          customdata: col.selectCustomData || [], // 动态下拉框的数据-数组
          dataIndex: col.dataIndex,
          title: col.title,
          editing: this.isEditing(record),
        }),
      };
    });

    return (
      <Table
        components={components}
        bordered
        dataSource={this.state.dataSource}
        columns={columns}
        rowClassName="editable-row"
        rowKey={(record, index) => record.key || index} // key值
        {...this.props.optsTable}
      />
    );
  }
}

export default EditableTable;
